home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / rayshade / graphtal.lzh / Graphtal.Amiga / Value.C < prev    next >
C/C++ Source or Header  |  1992-11-20  |  7KB  |  321 lines

  1. /*
  2.  * Value.C - methods for class Value,  which stores reals and strings. 
  3.  *
  4.  * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
  5.  *                     University of Berne, Switzerland
  6.  * Portions Copyright (C) 1990, Jonathan P. Leech
  7.  * All rights reserved.
  8.  *
  9.  * This software may be freely copied, modified, and redistributed
  10.  * provided that this copyright notice is preserved on all copies.
  11.  *
  12.  * You may not distribute this software, in whole or in part, as part of
  13.  * any commercial product without the express consent of the authors.
  14.  *
  15.  * There is no warranty or other guarantee of fitness of this software
  16.  * for any purpose.  It is provided solely "as is".
  17.  *
  18.  */
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include "Value.h"
  23. #include "Error.h"
  24.  
  25. Value::Value() 
  26. : type(REAL)
  27. {
  28.   realVal = 0.0;
  29. }
  30.       
  31. Value::Value(real val)
  32. : type(REAL)
  33. {
  34.   realVal = val;
  35. }
  36.  
  37. Value::Value(const char* str)
  38. : type(STRING)
  39. {
  40.   stringVal = new rcString(str);
  41. }
  42.       
  43. Value::Value(const rcString& s)
  44. : type(STRING)
  45. {
  46.   stringVal = new rcString(s);
  47. }
  48.  
  49. Value::Value(const Value& v)
  50. : type(v.type)
  51. {
  52.   if (v.type == REAL)
  53.     realVal = v.realVal;
  54.   else
  55.     stringVal = new rcString(*v.stringVal);
  56. }
  57.  
  58. Value::~Value()
  59. {
  60.   if (type == STRING)
  61.     delete stringVal;
  62. }
  63.  
  64. const Value& Value::operator=(const Value& v)
  65. {
  66.   if (this == &v)
  67.     return *this;
  68.  
  69.   if (type == STRING)
  70.     delete stringVal;
  71.  
  72.   type = v.type;
  73.   if (v.type == REAL)
  74.     realVal = v.realVal;
  75.   else
  76.     stringVal = new rcString(*v.stringVal);
  77.  
  78.   return *this;
  79. }
  80.  
  81. Value::operator real() const
  82. {
  83.   if (type == REAL)
  84.     return realVal;
  85.  
  86.   double retval;
  87.   char *ptr;
  88.  
  89.   retval = strtod(stringVal->chars(), &ptr);
  90.   if (*ptr == '\0')
  91.     return retval;
  92.   else 
  93.     Error(ERR_PANIC, "Value::operator real(): Can't convert rcString '" +
  94.                  *stringVal + "' to real");
  95.   return 0;
  96. }
  97.  
  98.  
  99. Value::operator rcString() const
  100. {
  101.   if (type == STRING)
  102.     return *stringVal;
  103.  
  104.   char ptr[100];
  105.   sprintf(ptr, "%g", realVal);
  106.   return rcString(ptr);
  107. }
  108.  
  109. int Value::toReal(real& x) const
  110. {
  111.   if (type == REAL) {
  112.     x = realVal;
  113.     return 1;
  114.   }
  115.  
  116.   double retval;
  117.   char *ptr;
  118.  
  119.   retval = strtod(stringVal->chars(), &ptr);
  120.   if (*ptr == '\0') {
  121.     x = retval;
  122.     return 1;
  123.   }
  124.   else
  125.     return 0;
  126. }
  127.  
  128. rcString Value::toString() const
  129. {
  130.   if (type == STRING)
  131.     return *stringVal;
  132.  
  133.   char ptr[100];
  134.   sprintf(ptr, "%g", realVal);
  135.   return rcString(ptr);
  136. }
  137.  
  138. ArgumentType Value::binary_type(const Value& v)
  139. {
  140.   switch(type) {
  141.     case REAL: 
  142.        if(v.type == REAL) return RR;
  143.        else if (v.type == STRING) return RS;
  144.        break;
  145.     case STRING:
  146.        if(v.type == STRING) return SS;
  147.        else if (v.type == REAL) return SR;
  148.        break;
  149.     default:
  150.        break;
  151.   }
  152.  
  153.   Error(ERR_PANIC, "Value::binary_type: strange value for 'type'");
  154.  
  155.   return UNKNOWN;
  156. }
  157.  
  158. Value Value::operator-() 
  159. {
  160.   switch (type) {
  161.     case REAL: return Value(-realVal);
  162.     default:   return *this;
  163.   }
  164. }
  165.  
  166. Value Value::operator+(const Value& v)
  167. {
  168.   switch (binary_type(v)) {
  169.     case RR: return Value(realVal + v.realVal);
  170.     case SS: return Value(*stringVal + *v.stringVal);
  171.     case RS: return Value(realVal + (real) v);
  172.     case SR: return Value(*stringVal + (rcString) v);
  173.     case UNKNOWN:
  174.     default: return Value();
  175.   }
  176. }
  177.  
  178. Value Value::operator-(const Value& v)
  179. {
  180.   switch (binary_type(v)) {
  181.     case RR: return Value(realVal - v.realVal);
  182.     default: return Value((real)*this - (real)v);
  183.   }
  184. }
  185.  
  186. Value Value::operator*(const Value& v)
  187. {
  188.   switch (binary_type(v)) {
  189.     case RR: return Value(realVal * v.realVal);
  190.     default: return Value((real)*this * (real)v);
  191.   }
  192. }
  193.  
  194. Value Value::operator/(const Value& v)
  195. {
  196.   switch (binary_type(v)) {
  197.     case RR: return Value(realVal / v.realVal);
  198.     default: return Value((real)*this / (real)v);
  199.   }
  200. }
  201.  
  202. Value Value::operator%(const Value& v)
  203. {
  204.   switch (binary_type(v)) {
  205.     case RR: return Value((long)realVal / (long)v.realVal);
  206.     default: return Value((long)real(*this) / (long)real(v));
  207.   }
  208. }
  209.  
  210. Value Value::operator!() 
  211. {
  212.   switch (type) {
  213.     case REAL: return Value(!realVal);
  214.     case STRING: return Value(stringVal->empty());
  215.     default:   return *this;
  216.   }
  217. }
  218.  
  219.  
  220. Value Value::operator&&(const Value& v)
  221. {
  222.   switch (binary_type(v)) {
  223.     case RR: return Value(realVal && v.realVal);
  224.     default: return Value((real)*this && (real)v);
  225.   }
  226. }
  227.  
  228. Value Value::operator||(const Value& v)
  229. {
  230.   switch (binary_type(v)) {
  231.     case RR: return Value(realVal || v.realVal);
  232.     default: return Value((real)*this || (real)v);
  233.   }
  234. }
  235.  
  236. Value Value::operator==(const Value& v)
  237. {
  238.   switch (binary_type(v)) {
  239.     case RR: return Value(realVal == v.realVal);
  240.     case SS: return Value(*stringVal == *v.stringVal);
  241.     case RS: return Value((rcString) *this ==  *v.stringVal);
  242.     case SR: return Value(*stringVal == (rcString) v);
  243.     case UNKNOWN:
  244.     default: return Value();
  245.   }
  246. }
  247.  
  248. Value Value::operator!=(const Value& v)
  249. {
  250.   switch (binary_type(v)) {
  251.     case RR: return Value(realVal != v.realVal);
  252.     case SS: return Value(*stringVal != *v.stringVal);
  253.     case RS: return Value((rcString) *this !=  *v.stringVal);
  254.     case SR: return Value(*stringVal != (rcString) v);
  255.     case UNKNOWN:
  256.     default: return Value();
  257.   }
  258. }
  259.  
  260.  
  261. Value Value::operator<(const Value& v)
  262. {
  263.   switch (binary_type(v)) {
  264.     case RR: return Value(realVal < v.realVal);
  265.     case SS: return Value(*stringVal < *v.stringVal);
  266.     case RS: return Value((rcString) *this <  *v.stringVal);
  267.     case SR: return Value(*stringVal < (rcString) v);
  268.     case UNKNOWN:
  269.     default: return Value();
  270.   }
  271. }
  272.  
  273. Value Value::operator<=(const Value& v)
  274. {
  275.   switch (binary_type(v)) {
  276.     case RR: return Value(realVal <= v.realVal);
  277.     case SS: return Value(*stringVal <= *v.stringVal);
  278.     case RS: return Value((rcString) *this <=  *v.stringVal);
  279.     case SR: return Value(*stringVal <= (rcString) v);
  280.     case UNKNOWN:
  281.     default: return Value();
  282.   }
  283. }
  284.  
  285. Value Value::operator>(const Value& v)
  286. {
  287.   switch (binary_type(v)) {
  288.     case RR: return Value(realVal > v.realVal);
  289.     case SS: return Value(*stringVal > *v.stringVal);
  290.     case RS: return Value((rcString) *this >  *v.stringVal);
  291.     case SR: return Value(*stringVal > (rcString) v);
  292.     case UNKNOWN:
  293.     default: return Value();
  294.   }
  295. }
  296.  
  297. Value Value::operator>=(const Value& v)
  298. {
  299.   switch (binary_type(v))
  300.   {
  301.     case RR: return Value(realVal >= v.realVal);
  302.     case SS: return Value(*stringVal >= *v.stringVal);
  303.     case RS: return Value((rcString) *this >=  *v.stringVal);
  304.     case SR: return Value(*stringVal >= (rcString) v);
  305.     case UNKNOWN:
  306.     default: return Value();
  307.   }
  308. }
  309.  
  310. ostream& operator<<(ostream& os, const Value& v)
  311. {
  312.   if (v.type == REAL)
  313.     os << v.realVal;
  314.   else if (v.type == STRING)
  315.     os << '\"' << *v.stringVal << '\"';
  316.   else
  317.     os << "Not know type of Value!\n";
  318.  
  319.   return os;
  320. }
  321.